function ShaderManager() {};

ShaderManager.prototype = {
    setTable: function(index, vsid, fsid, initFunc, setupFunc) {
        //var gl = this.gl;
        var program = gl.createProgram();
        gl.attachShader(program, this.initShader(vsid));
        gl.attachShader(program, this.initShader(fsid));
        gl.linkProgram(program);

        if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
            alert("Could not initialise shaders");
        }
        //program.gl = gl;
        gl.useProgram(program);
        program.init = initFunc;
        program.init();     
        //initFunc.apply(program, [gl]);
        program.setup = setupFunc;
        
        
        this.table[index] = program;
        this.program = program;
    },

    initShader: function(id) {
        //var gl = this.gl;
        var shaderScript = document.getElementById(id);
            if (!shaderScript) {
            return null;
        }

        var str = "";
        var k = shaderScript.firstChild;
        while (k) {
            if (k.nodeType == 3) {
                str += k.textContent;
            }
            k = k.nextSibling;
        }

        var shader;
        if (shaderScript.type == "x-shader/x-fragment") {
            shader = gl.createShader(gl.FRAGMENT_SHADER);
        } else if (shaderScript.type == "x-shader/x-vertex") {
            shader = gl.createShader(gl.VERTEX_SHADER);
        } else {
            return null;
        }

        gl.shaderSource(shader, str);
        gl.compileShader(shader);

        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            alert(gl.getShaderInfoLog(shader));
            return null;
        }

        return shader;
    },
    setup: function(model) {
        var index = model.shaderId;
        var program = this.table[index];
        //this.gl.useProgram(this.table[index]);
        gl.useProgram(program);
        gl.uniformMatrix4fv(program.locUnifPmatrix, false, this.camera.pMatrixFlatten);
        //this.table[index].init();
        //this.table[index].setup(this.camera.pMatrix, this.matrixStack.top(), model);
        program.setup(this.matrixStack.top(), model);
    }
}


ShaderManager.create = function(camera, matrixStack){
    var sman = new ShaderManager();
    sman.table = [];
    sman.camera = camera;
    sman.matrixStack = matrixStack;
    return sman;
}
